home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 11
/
Cream of the Crop 11-1.iso
/
games
/
ted5.zip
/
LIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-04
|
19KB
|
1,012 lines
#include "ted5.h"
#pragma hdrstop
extern char far TEDCHAR,far VGAPAL;
void Quit(char *string);
void drawchar(int x,int y,int chr);
void centerwindow (int width, int height);
int win_xl,win_yl,win_xh,win_yh;
int screencenterx = 19,screencentery = 11;
unsigned char keydown[256];
unsigned leftedge,yshift,xormask,MouseStatus,sx,sy;
void interrupt (*oldint9) ()=NULL;
enum {false,true} boolean;
memptr CGAfont,VGAfont;
unsigned doubled[256];
//
// Special vars to handle EGA3 mouse mode
//
int EGA3mx,EGA3my;
////////////////////////////////////////////////////////////////////
//
// Return a file's length
//
////////////////////////////////////////////////////////////////////
long filelen(char *filename)
{
long size;
int handle;
if ((handle=open(filename,O_BINARY))==-1)
return 0;
size=filelength(handle);
close(handle);
return size;
}
////////////////////////////////////////////////////////////////////
//
// WaitVBL
//
////////////////////////////////////////////////////////////////////
void WaitVBL(int times)
{
asm mov cx,times
asm mov dx,crtcaddr
asm add dx,6
waitvbl1:
asm in al,dx
asm test al,00001000b //;look for vbl
asm jnz waitvbl1
waitvbl2:
asm in al,dx
asm test al,00001000b //;look for vbl
asm jz waitvbl2
asm loop waitvbl1
}
////////////////////////////////////////////////////////////////////
//
// Int9ISR
// Called for every keypress. Keeps track of which keys are down, and passes
// the key on to DOS after clearing the dos buffer (max 1 char in buffer).
//
////////////////////////////////////////////////////////////////////
void interrupt Int9ISR ()
{
int key = inportb (0x60); /* get the key pressed */
if (key>127)
keydown [key-128] = false; /* break scan code */
else
{
keydown [key] = true; /* make scan code */
poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */
}
asm {
push ax
push bx
push cx
push dx
push si
push di
push bp
}
oldint9 (); /* give it to DOS */
asm {
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
}
outport (0x20,0x20); /* tell the int manager we got it */
}
////////////////////////////////////////////////////////////////////
//
// SetupKBD
// Clears the keydown array and installs the INT 9 ISR if it isn't already
// hooked up.
//
////////////////////////////////////////////////////////////////////
void SetupKBD ()
{
void far *vect = getvect (9);
int i;
for (i=0;i<128;i++) /* clear our key down table */
keydown[i]= false;
poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */
if ( &Int9ISR != vect ) /* is our handler allready set up? */
{
oldint9 = vect;
setvect (9,Int9ISR);
}
}
////////////////////////////////////////////////////////////////////
//
// ShutdownKBD
// Sets the int 9 vector back to oldint 9
//
////////////////////////////////////////////////////////////////////
void ShutdownKBD ()
{
if (oldint9 != NULL)
setvect (9,oldint9);
}
////////////////////////////////////////////////////////////////////
//
// clearkeys
// Clears out the bios buffer and zeros out the keydown array
//
////////////////////////////////////////////////////////////////////
void clearkeys (void)
{
int i;
while (bioskey (1))
bioskey(0);
for (i=0;i<128;i++)
keydown [i]=0;
}
////////////////////////////////////////////////////////////////////
//
// Mouse Routines
//
////////////////////////////////////////////////////////////////////
int MouseInit(void)
{
union REGS regs;
unsigned char far *vector;
if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL) return 0;
if (*vector == 207)
return MouseStatus = 0;
_AX=0;
geninterrupt(0x33);
EGA3mx=800/2;
EGA3my=600/2;
//
// Set CGA mouse cursor (normal one sucks)
//
if (videomode==CGA)
{
static unsigned CGAcursor[]=
{
0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
};
_BX=0;
_CX=0;
_DX=FP_OFF(CGAcursor);
_ES=_DS;
_AX=9;
geninterrupt(0x33);
}
return MouseStatus = 1;
}
void MouseOrigin(int x,int y)
{
if (!MouseStatus) return;
_CX=x;
_DX=y;
_AX=4;
geninterrupt(0x33);
}
void MouseLimits(int xmin,int xmax,int ymin,int ymax)
{
if (!MouseStatus) return;
_CX=xmin;
_DX=xmax;
_AX=7;
geninterrupt(0x33);
_CX=ymin;
_DX=ymax;
_AX=8;
geninterrupt(0x33);
}
void MouseHide(void)
{
if (!MouseStatus) return;
_AX=2;
geninterrupt(0x33);
}
void MouseShow(void)
{
if (!MouseStatus) return;
_AX=1;
geninterrupt(0x33);
}
int MouseButton(void)
{
union REGS regs;
if (!MouseStatus) return 0;
regs.x.ax=3;
int86(0x33,®s,®s);
return(regs.x.bx);
}
void MouseCoords(int *x,int *y)
{
union REGS regs;
if (!MouseStatus)
return;
regs.x.ax=3;
int86(0x33,®s,®s);
*x=regs.x.cx;
*y=regs.x.dx;
*x/=2;
if (videomode==EGA2)
*x*=2;
}
/////////////////////////
//
// print
// Prints a string at sx,sy. No clipping!!!
//
/////////////////////////
void print (const char *str)
{
char ch;
while ((ch=*str++) != 0)
if (ch == '\n')
{
sy++;
sx=leftedge;
}
else if (ch == '\r')
sx=leftedge;
else
drawchar (sx++,sy,ch);
}
void fprint (const char huge *str)
{
char ch;
while ((ch=*str++) != 0)
if (ch == '\n')
{
sy++;
sx=leftedge;
}
else if (ch == '\r')
sx=leftedge;
else
drawchar (sx++,sy,ch);
}
////////////////////////////////////////////////////////////////////
//
// print hex byte
//
////////////////////////////////////////////////////////////////////
void printhexb(unsigned char value)
{
int loop;
char hexstr[16]="0123456789ABCDEF",str[2]="";
for (loop=0;loop<2;loop++)
{
str[0]=hexstr[(value>>(1-loop)*4)&15];
print(str);
}
}
////////////////////////////////////////////////////////////////////
//
// print hex
//
////////////////////////////////////////////////////////////////////
void printhex(unsigned value)
{
print("$");
printhexb(value>>8);
printhexb(value&0xff);
}
////////////////////////////////////////////////////////////////////
//
// print int
//
////////////////////////////////////////////////////////////////////
void printint(unsigned value)
{
char temp[10];
ultoa((unsigned long)value,temp,10);
print(temp);
}
////////////////////////////////////////////////////////////////////
//
// print bin
//
////////////////////////////////////////////////////////////////////
void printbin(unsigned value)
{
int loop;
print("%");
for (loop=0;loop<16;loop++)
if ((value>>15-loop)&1) print("1"); else print("0");
}
////////////////////////////////////////////////////////////////////
//
// input unsigned
//
////////////////////////////////////////////////////////////////////
unsigned inputint(int numchars)
{
char string[18]="",digit,hexstr[16]="0123456789ABCDEF";
unsigned value,loop,loop1;
if (!input(string,numchars))
return ESCOUT;
if (string[0]=='$')
{
int digits;
digits=strlen(string)-2;
if (digits<0) return 0;
for (value=0,loop1=0;loop1<=digits;loop1++)
{
digit=toupper(string[loop1+1]);
for (loop=0;loop<16;loop++)
if (digit==hexstr[loop])
{
value|=(loop<<(digits-loop1)*4);
break;
}
}
}
else if (string[0]=='%')
{
int digits;
digits=strlen(string)-2;
if (digits<0) return 0;
for (value=0,loop1=0;loop1<=digits;loop1++)
{
if (string[loop1+1]<'0' || string[loop1+1]>'1') return 0;
value|=(string[loop1+1]-'0')<<(digits-loop1);
}
}
else value=atoi(string);
return value;
}
////////////////////////////////////////////////////////////////////
//
// line input routine
//
////////////////////////////////////////////////////////////////////
int input(char *string,int max)
{
char key;
int count=0,loop;
do {
key=get()&0xff;
if ((key==127 || key==8)&&count>0)
{
count--;
drawchar(sx,sy,' ');
sx--;
}
if (key>=' ' && key<='z' && count<max)
{
*(string+count++)=key;
drawchar(sx++,sy,key);
}
} while (key!=27 && key!=13);
for (loop=count;loop<max;loop++) *(string+loop)=0;
while(keydown[1]); // don't let ESC repeat
if (key==13)
{
while(keydown[0x1c]);
return 1;
}
return 0;
}
void bar (int xl, int yl, int xh, int yh, int ch)
{
int x,y;
for (y=yl;y<=yh;y++)
for (x=xl;x<=xh;x++)
drawchar (x,y,ch);
}
/////////////////////////
//
// get
// Flash a cursor at sx,sy and waits for a user bioskey
//
/////////////////////////
int get (void)
{
int cycle,key;
do
{
cycle = 9;
while (!(key = bioskey(1)) && cycle<11)
{
drawchar (sx,sy,cycle++);
WaitVBL (5);
}
} while (key == 0);
drawchar (sx,sy,' ');
return bioskey(0); // take it out of the buffer
}
////////////////////////////////////////////////////////////////////
//
// drawchar
//
////////////////////////////////////////////////////////////////////
void drawchar(int x,int y,int chr)
{
switch(videomode)
{
case CGA: CGAcharout(x,y,chr); break;
case EGA1:
case EGA2: EGAcharout(x,y,chr,videomode); break;
case VGA: VGAcharout(x,y,chr);
}
}
////////////////////////////////////////////////////////////////////
//
// Set a video mode
//
////////////////////////////////////////////////////////////////////
void setvideo(video vid)
{
//
// create CGA font (if not already created)
//
if (vid==CGA && !CGAfont)
{
unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR));
unsigned i,j,huge *newfont;
centerwindow(20,1);
print("Creating CGA font...");
MMAllocate(&CGAfont,2048);
newfont=MK_FP(CGAfont,0);
for(i=0;i<127;i++)
for(j=0;j<8;j++)
(unsigned)*(newfont+i*8+j)=doubled[*(oldfont+i*8+j)]; //color=|0xaaaa;
}
else
//
// OR create VGA font (if not already created)
//
if (vid==VGA && !VGAfont)
{
unsigned char huge *oldfont=MK_FP(FP_SEG(&TEDCHAR),FP_OFF(&TEDCHAR)),
huge *newfont;
unsigned i,j,k;
unsigned char bitbyte[2]={0,0xff}; // colors={0x7e,0x78};
centerwindow(20,1);
print("Creating VGA font...");
MMAllocate(&VGAfont,0x2000);
newfont=MK_FP(VGAfont,0);
for(i=0;i<128;i++)
for(j=0;j<8;j++)
for(k=0;k<8;k++)
*(newfont+i*64+j*8+k)=bitbyte[(*(oldfont+i*8+j)>>(7-k))&1];
}
//
// Now, change video modes!
//
switch(vid)
{
case TEXT: _AX=3; break;
case CGA:
screencenterx=19;
screencentery=11;
scrnbot=199;
scrnrgt=319;
_AX=4;
break;
case EGA1:
screencenterx=19;
screencentery=11;
scrnbot=199;
scrnrgt=319;
_AX=0x0d;
break;
case EGA2:
screencenterx=39;
screencentery=29;
scrnbot=479;
scrnrgt=638;
_AX=0x12;
break;
case VGA:
_AX=0x13;
screencenterx=19;
screencentery=11;
scrnbot=199;
scrnrgt=319;
}
geninterrupt(0x10);
videomode=vid;
//
// Set CGA mouse cursor (normal one sucks)
//
if (vid==CGA)
{
static unsigned CGAcursor[]=
{
0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03,
0xff03,0xffff,0xffff,0xffff,0xffff,0xffff,
0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c,
0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000
};
_BX=0;
_CX=0;
_DX=FP_OFF(CGAcursor);
_ES=_DS;
_AX=9;
geninterrupt(0x33);
}
else
//
// Move EGA font into LATCH memory!
//
if (vid==EGA1 || vid==EGA2)
{
unsigned i,s=FP_SEG(&TEDCHAR),o=FP_OFF(&TEDCHAR);
outport(GCindex,GCmode);
for (i=0;i<4;i++)
{
outport(SCindex,SCmapmask | (1<<i)*256);
movedata(s,o+i*0x400,0xaf00,0,0x400);
}
}
else
//
// OR set the VGA palette
//
if (vid==VGA) // set VGA palette
{
_BX=0;
_CX=0x100;
_DX=FP_OFF(&VGAPAL);
_ES=FP_SEG(&VGAPAL);
_AX=0x1012;
geninterrupt(0x10);
}
}
////////////////////////////////////////////////////////////////////
//
// Quit the fuck outta here!
//
////////////////////////////////////////////////////////////////////
void Quit(char *string)
{
Unhook();
setvideo(TEXT);
poke(0,0x41a,peek(0,0x41c)); // clear keyboard
if (string[0])
{
printf("TED5 ERROR: %s",string);
exit(1);
}
printf("Thanks for using TED5!");
nosound();
exit(0);
}
//////////////////////////
//
// drawwindow
// draws a bordered window and homes the cursor
//
//////////////////////////
void drawwindow (int xl, int yl, int xh, int yh)
{
int x,y;
win_xl=xl;
win_yl=yl;
win_xh=xh;
win_yh=yh; // so the window can be erased
drawchar (xl,yl,1);
for (x=xl+1;x<xh;x++)
drawchar (x,yl,2);
drawchar (xh,yl,3);
for (y=yl+1;y<yh;y++)
{
drawchar (xl,y,4);
for (x=xl+1;x<xh;x++)
drawchar (x,y,' ');
drawchar (xh,y,5);
}
drawchar (xl,yh,6);
for (x=xl+1;x<xh;x++)
drawchar (x,yh,7);
drawchar (xh,yh,8);
sx = leftedge = xl+1;
sy = yl+1;
}
////////////////////////////
//
// erasewindow
// clears out the last window and it's border to spaces
//
///////////////////////////
void erasewindow (void)
{
bar (win_xl,win_yl,win_xh,win_yh,' ');
}
/////////////////////////////
//
// centerwindow
// Centers a drawwindow of the given size
//
/////////////////////////////
void centerwindow (int width, int height)
{
int xl = screencenterx-width/2;
int yl = screencentery-height/2;
drawwindow (xl,yl,xl+width+1,yl+height+1);
}
///////////////////////////////
//
// expwin {h / v}
// Grows the window outward
//
///////////////////////////////
void expwinh (int width, int height)
{
if (width > 2)
expwinh (width-2,height);
WaitVBL (1);
centerwindow (width,height);
}
void expwinv (int width, int height)
{
if (height >2)
expwinv (width,height-2);
WaitVBL (1);
centerwindow (width,height);
}
void expwin (int width, int height)
{
if (width > 2)
{
if (height >2)
expwin (width-2,height-2);
else
expwinh (width-2,height);
}
else
if (height >2)
expwinv (width,height-2);
WaitVBL (1);
centerwindow (width,height);
}
////////////////////////////////////////////////////////////
//
// Save a *LARGE* file from a FAR buffer!
// by John Romero (C) 1990 Gamer's Edge
//
////////////////////////////////////////////////////////////
void SaveFile(char *filename,char huge *buffer,long offset,long size)
{
unsigned int handle,buf1,buf2,offlo,offhi,sizelo,sizehi;
buf1=FP_OFF(buffer);
buf2=FP_SEG(buffer);
offlo=offset&0xffff;
offhi=offset>>16;
sizelo=size&0xffff;
sizehi=size>>16;
asm mov ax,offlo
asm or ax,offhi
asm jz CREATEIT
asm mov dx,filename
asm mov ax,3d02h // OPEN w/handle (read only)
asm int 21h
asm jnc L0
return;
L0:
asm mov handle,ax
asm mov bx,handle
asm mov dx,offlo
asm mov cx,offhi
asm mov ax,4200h
asm int 21h // SEEK (to file offset)
asm jc out
asm jmp DOSAVE
CREATEIT:
asm mov dx,filename
asm mov ax,3c00h // CREATE w/handle (read only)
asm xor cx,cx
asm int 21h
asm jc out
asm mov handle,ax
DOSAVE:
asm cmp WORD PTR sizehi,0 // larger than 1 segment?
asm je L2
L1:
asm push ds
asm mov bx,handle
asm mov cx,8000h
asm mov dx,buf1
asm mov ax,buf2
asm mov ds,ax
asm mov ah,40h // WRITE w/handle
asm int 21h
asm pop ds
asm add WORD PTR buf2,800h // bump ptr up 1/2 segment
asm sub WORD PTR sizelo,8000h // done yet?
asm sbb WORD PTR sizehi,0
asm cmp WORD PTR sizehi,0
asm ja L1
asm cmp WORD PTR sizelo,8000h
asm jae L1
L2:
asm push ds
asm mov bx,handle
asm mov cx,sizelo
asm mov dx,buf1
asm mov ax,buf2
asm mov ds,ax
asm mov ah,40h // WRITE w/handle
asm int 21h
asm pop ds
out:
asm mov bx,handle // CLOSE w/handle
asm mov ah,3eh
asm int 21h
}
////////////////////////////////////////////////////////////
//
// Load a *LARGE* file into a FAR buffer!
// by John Romero (C) 1990 Gamer's Edge
//
////////////////////////////////////////////////////////////
unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size)
{
unsigned handle,flength1=0,flength2=0,buf1,buf2,len1,len2,
rsize1,rsize2,roffset1,roffset2;
rsize1=size&0xffff;
rsize2=size>>16;
roffset1=offset&0xffff;
roffset2=offset>>16;
buf1=FP_OFF(buffer);
buf2=FP_SEG(buffer);
asm mov dx,filename
asm mov ax,3d00h // OPEN w/handle (read only)
asm int 21h
asm jnc L_0
return 0;
L_0:
asm mov handle,ax
asm mov bx,ax
asm xor cx,cx
asm xor dx,dx
asm mov ax,4202h
asm int 21h // SEEK (find file length)
asm jc out
asm mov flength1,ax
asm mov len1,ax
asm mov flength2,dx
asm mov len2,dx
asm mov ax,rsize1 // was a size specified?
asm or ax,rsize1
asm jz LOADALL
asm mov ax,rsize1 // only load size requested
asm mov len1,ax
asm mov ax,rsize2
asm mov len2,ax
LOADALL:
asm mov bx,handle
asm mov dx,roffset1
asm mov cx,roffset2
asm mov ax,4200h
asm int 21h // SEEK (to file offset)
asm jc out
asm cmp WORD PTR len2,0 // MULTI-SEGMENTAL?
asm je L_2
L_1:
asm push ds
asm mov bx,handle
asm mov cx,8000h // read 32K chunks
asm mov dx,buf1
asm mov ax,buf2
asm mov ds,ax
asm mov ah,3fh // READ w/handle
asm int 21h
asm pop ds
asm jc out
asm add WORD PTR buf2,800h
asm sub WORD PTR len1,8000h
asm sbb WORD PTR len2,0
asm cmp WORD PTR len2,0
asm ja L_1
asm cmp WORD PTR len1,8000h
asm jae L_1
L_2:
asm push ds
asm mov bx,handle
asm mov cx,len1
asm mov dx,buf1
asm mov ax,buf2
asm mov ds,ax
asm mov ah,3fh // READ w/handle
asm int 21h
asm pop ds
asm jmp exit
out:
asm mov WORD PTR flength2,0
asm mov WORD PTR flength1,0
exit:
asm mov bx,handle // CLOSE w/handle
asm mov ah,3eh
asm int 21h
return (flength2*0x10000+flength1);
}
////////////////////////////////////////////////////////////
//
// Allocate memory and load file in
//
////////////////////////////////////////////////////////////
void LoadIn(char *filename,void _seg **baseptr)
{
char errstr[80];
int handle;
long len;
if ((handle=open(filename,O_BINARY))==-1)
{
strcpy(errstr,"Error loading file ");
strcat(errstr,filename);
Quit(errstr);
}
len=filelength(handle);
close(handle);
MMAllocate((memptr *)baseptr,len);
LoadFile(filename,MK_FP(*baseptr,0),0,0);
}